package cn.chainco.cts.security;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
import cn.chainco.cts.security.validator.BusinessValidator;
import cn.chainco.cts.security.validator.PreResult;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

@SuppressWarnings("unchecked")
public class BinsinessInterceptor extends AbstractInterceptor{
	private static final long serialVersionUID = 6510734781446148486L;
	private static final String NO_AUTHORISE = "needAuth"; // 权限验证不通过跳转页面
	private static Set<String> needValidateActionSet; // 需要验证的Action集合
	private BusinessValidator businessValidator;
	public static final int ACCESS_PERMIT = 1;
	public static final int ACCESS_DENIAL = 0;
	public static final int ACCESS_OTHER = -1;

	@Override
	public void init(){
		initNeedValidateActionSet();
		super.init();
	}

	// 初始化需要验证的Action
	private void initNeedValidateActionSet(){
		if(needValidateActionSet == null){
			needValidateActionSet = new HashSet<String>();
		}
		Class<?> clazz = businessValidator.getClass();
		Method[] methods = clazz.getDeclaredMethods();
		for(Method method: methods){
			needValidateActionSet.add(method.getName());
		}
	}

	@Override
	public String intercept(ActionInvocation actionInvocation) throws Exception{
		try{
			String methodName = actionInvocation.getInvocationContext().getName();
			if(isNeedValidateAction(methodName)){
				Class clazz = businessValidator.getClass();
				Method method = clazz.getDeclaredMethod(methodName, new Class[]{ActionInvocation.class});
				PreResult preResult = method.getAnnotation(PreResult.class);
				if(preResult == null){
					// 在进入拦截方法之前执行
					int result = (Integer)method.invoke(businessValidator, new Object[]{actionInvocation});
					if(result != ACCESS_PERMIT){
						return NO_AUTHORISE;
					}
				}else{
					// 在拦截方法返回之前执行
					new PreActionReturnInterceptor(actionInvocation, businessValidator, method);
				}
			}
		}catch(RuntimeException e){
			e.printStackTrace();
		}
		return actionInvocation.invoke();
	}

	private boolean isNeedValidateAction(String method){
		if(needValidateActionSet == null){
			initNeedValidateActionSet();
		}
		return needValidateActionSet.contains(method);
	}

	public BusinessValidator getBusinessValidator(){
		return businessValidator;
	}

	public void setBusinessValidator(BusinessValidator businessValidator){
		this.businessValidator = businessValidator;
	}
}